home *** CD-ROM | disk | FTP | other *** search
/ Usenet 1993 July / InfoMagic USENET CD-ROM July 1993.ISO / sources / unix / volume9 / elm2 / part09 < prev    next >
Encoding:
Internet Message Format  |  1987-03-08  |  50.3 KB

  1. Subject:  v09i009:  ELM Mail System, Part09/19
  2. Newsgroups: mod.sources
  3. Approved: rs@mirror.TMC.COM
  4.  
  5. Submitted by: Dave Taylor <hplabs!taylor>
  6. Mod.sources: Volume 9, Issue 9
  7. Archive-name: elm2/Part09
  8.  
  9. #! /bin/sh
  10. # This is a shell archive.  Remove anything before this line,
  11. # then unpack it by saving it in a file and typing "sh file".
  12. # If this archive is complete, you will see the message:
  13. #        "End of archive 9 (of 19)."
  14. # Contents:  Makefile Makefile.mstr src/forms.c src/return_addr.c
  15. #   src/save_opts.c
  16. PATH=/bin:/usr/bin:/usr/ucb ; export PATH
  17. echo shar: Extracting \"Makefile\" \(9596 characters\)
  18. if test -f Makefile ; then 
  19.   echo shar: Will not over-write existing file \"Makefile\"
  20. else
  21. sed "s/^X//" >Makefile <<'END_OF_Makefile'
  22. X#
  23. X#  Makefile for the entire ELM mail system
  24. X#
  25. X#         (C) Copyright 1986, Dave Taylor
  26. X#
  27. X#  Last modification: October 8th, 1986
  28. X
  29. XSHELL=/bin/sh
  30. X
  31. X#########################
  32. X#
  33. X# The following entries need to be customized for the local site:  
  34. X#    The first is the address of the data-cassette drive to allow
  35. X# easy tape copies to be made, and the second is the final location 
  36. X# that all the software should be installed in when 'make install'
  37. X# is run.
  38. X#
  39. X#########################
  40. X
  41. XTAPE=   /dev/rct 
  42. XDEST=   /usr/local/bin
  43. X
  44. XLIB=    /usr/local/lib
  45. XMAN=    /usr/man/man1
  46. XCATMAN= /usr/man/cat1
  47. XSHAR=   /usr/local/bin/shar -s 60000
  48. X
  49. XDEFINE = -DBSD
  50. XLIB2   = -lcurses
  51. X
  52. X#########################
  53. X
  54. XLIBS=   -ltermcap
  55. XCFLAGS= -O
  56. XCC=    /bin/cc
  57. XRM=    /bin/rm -f
  58. XMV=     /bin/mv -f
  59. XCP=    /bin/cp
  60. X
  61. X# if you want to use "nroff", change this...
  62. X
  63. XFORMATTER = /usr/bin/troff
  64. XTBL       = cat
  65. X
  66. XDOCS=   Alias.guide Config.guide Elm.coversheet Filter.guide Ref.guide     \
  67. X    Forms.guide Users.guide answer.1 autoreply.1 checkalias.1          \
  68. X    elm.1 fastmail.1 filter.1 from.1 listalias.1 messages.1 newalias.1 \
  69. X    newmail.1 printmail.1 readmsg.1 trim-headers.1 wnewmail.1
  70. X
  71. XUTILSRC= utils/answer.c utils/arepdaemon.c utils/autoreply.c           \
  72. X    utils/fastmail.c utils/from.c utils/newalias.c \
  73. X    utils/newmail.c utils/printmail.c utils/readmsg.c utils/wnewmail.c \
  74. X    utils/trim-headers
  75. X
  76. XFILTSRC= filter/actions.c filter/filter.c filter/parse.c filter/rules.c     \
  77. X    filter/summarize.c filter/utils.c
  78. X
  79. XELMSRC=    src/addr_utils.c src/alias.c src/aliasdb.c src/aliaslib.c src/args.c  \
  80. X    src/bounceback.c src/builtin.c src/calendar.c src/connect_to.c          \
  81. X    src/curses.c src/date.c src/delete.c src/domains.c src/edit.c          \
  82. X    src/editmsg.c src/elm.c src/encode.c src/errno.c src/file.c          \
  83. X    src/file_utils.c src/fileio.c src/forms.c src/getopt.c src/hdrconfg.c \
  84. X    src/help.c src/initialize.c src/input_utils.c src/leavembox.c          \
  85. X    src/limit.c src/mailmsg1.c src/mailmsg2.c src/mailtime.c src/mkhdrs.c \
  86. X    src/newmbox.c src/opt_utils.c src/options.c src/output_utils.c        \
  87. X    src/pattern.c src/pmalloc.c src/quit.c src/read_rc.c src/remail.c     \
  88. X    src/reply.c src/return_addr.c src/save_opts.c src/savecopy.c          \
  89. X    src/screen.c src/showmsg.c src/signals.c src/softkeys.c src/sort.c    \
  90. X    src/string2.c src/strings.c src/syscall.c src/utils.c src/validname.c
  91. X
  92. XMISCHDRS  = hdrs/defs.h hdrs/sysdefs.h
  93. XELMHDRS   = hdrs/headers.h 
  94. XFILTHDRS  = hdrs/filter.h
  95. XMAINHDRS  = hdrs/elm.h
  96. X
  97. X################
  98. X
  99. Xall:    bin/elm filter utils 
  100. X    @echo Everything is up to date!
  101. X
  102. Xdocumentation:  doc/Users.fmtd doc/Ref.fmtd doc/Config.fmtd doc/Alias.fmtd \
  103. X        doc/Form.fmtd doc/Filter.fmtd
  104. X    
  105. Xdoc/Users.fmtd: doc/Users.guide
  106. X    ${TBL} doc/Users.guide | ${FORMATTER} -mm > doc/Users.fmtd
  107. X
  108. Xdoc/Form.fmtd: doc/Form.guide
  109. X    ${FORMATTER} -mm doc/Form.guide > doc/Form.fmtd
  110. X
  111. Xdoc/Filter.fmtd: doc/Filter.guide
  112. X    ${FORMATTER} -mm doc/Filter.guide > doc/Filter.fmtd
  113. X
  114. Xdoc/Ref.fmtd: doc/Ref.guide
  115. X    ${FORMATTER} -mm doc/Ref.guide > doc/Ref.fmtd
  116. X
  117. Xdoc/Config.fmtd:  doc/Config.guide
  118. X    ${TBL} doc/Config.guide | ${FORMATTER} -mm > doc/Config.fmtd
  119. X
  120. Xdoc/Alias.fmtd:  doc/Alias.guide
  121. X    ${FORMATTER} -mm doc/Alias.guide > doc/Alias.fmtd
  122. X
  123. Xbin/elm: ${ELMSRC} ${MISCHDRS} ${ELMHDRS} ${MAINHDRS}
  124. X    cd src;make 'DEFINE=${DEFINE}' 'LIB2=${LIB2}' ../bin/elm
  125. X    
  126. Xbin/utils: ${UTILSRC} ${MISCHHDRS}
  127. X    cd utils; make 'DEFINE=${DEFINE}' 'LIBS=${LIB2}' all
  128. X
  129. Xbin/filter: ${FILTSRC} ${FILTHDR}
  130. X    cd filter; make 'DEFINE=${DEFINE}' 'LIBS=${LIB2}' all
  131. X
  132. Xinstall: all
  133. X    ${CP} bin/elm          ${DEST}/elm
  134. X    ${CP} bin/from         ${DEST}/from
  135. X    ${CP} bin/newalias     ${DEST}/newalias
  136. X    ${CP} bin/printmail    ${DEST}/printmail
  137. X    ${CP} bin/fastmail     ${DEST}/fastmail
  138. X    ${CP} bin/readmsg      ${DEST}/readmsg
  139. X    ${CP} bin/newmail      ${DEST}/newmail
  140. X    ${CP} bin/wnewmail     ${DEST}/wnewmail
  141. X    ${CP} bin/checkalias   ${DEST}/checkalias
  142. X    ${CP} bin/messages     ${DEST}/messages
  143. X    ${CP} bin/trim-headers ${DEST}/trim-headers
  144. X    ${CP} bin/arepdaemon   ${DEST}/arepdaemon
  145. X    ${CP} bin/autoreply    ${DEST}/autoreply
  146. X    ${CP} bin/listalias    ${DEST}/listalias
  147. X    ${CP} bin/filter       ${DEST}/filter
  148. X    ${RM} ${CATMAN}/elm.1 ${CATMAN}/from.1 \
  149. X          ${CATMAN}/newalias.1 ${CATMAN}/printmail.1 \
  150. X          ${CATMAN}/fastmail.1 ${CATMAN}/elm.1 \
  151. X          ${CATMAN}/readmsg.1 ${CATMAN}/answer.1 \
  152. X          ${CATMAN}/newmail.1 ${CATMAN}/checkalias.1 \
  153. X          ${CATMAN}/autoreply.1 ${CATMAN}/wnewmail.1 \
  154. X          ${CATMAN}/messages.1 ${CATMAN}/trim-headers.1 \
  155. X          ${CATMAN}/listalias.1 ${CATMAN}/filter.1
  156. X    ${CP} doc/elm.1        ${MAN}/elm.1
  157. X    ${CP} doc/from.1       ${MAN}/from.1
  158. X    ${CP} doc/newalias.1   ${MAN}/newalias.1
  159. X    ${CP} doc/printmail.1  ${MAN}/printmail.1
  160. X    ${CP} doc/fastmail.1   ${MAN}/fastmail.1
  161. X    ${CP} doc/checkalias.1 ${MAN}/checkalias.1
  162. X    ${CP} doc/messages.1   ${MAN}/messages.1
  163. X    ${CP} doc/trim-headers.1 ${MAN}/trim-headers.1
  164. X    ${CP} doc/autoreply.1  ${MAN}/autoreply.1
  165. X    ${CP} doc/answer.1     ${MAN}/answer.1
  166. X    ${CP} doc/readmsg.1    ${MAN}/readmsg.1
  167. X    ${CP} doc/newmail.1    ${MAN}/newmail.1
  168. X    ${CP} doc/wnewmail.1   ${MAN}/wnewmail.1
  169. X    ${CP} doc/listalias.1  ${MAN}/listalias.1
  170. X    ${CP} doc/filter.1     ${MAN}/filter.1
  171. X    ${CP} doc/elm-help.?   ${LIB}
  172. X    ${CP} doc/elmrc-info   ${LIB}
  173. X    chmod a+rx ${DEST}/from ${DEST}/newalias \
  174. X           ${DEST}/printmail ${DEST}/fastmail \
  175. X           ${DEST}/readmsg ${DEST}/trim-headers \
  176. X           ${DEST}/checkalias ${DEST}/autoreply \
  177. X           ${DEST}/newmail ${DEST}/wnewmail ${DEST}/messages \
  178. X           ${DEST}/listalias
  179. X    chgrp mail ${DEST}/elm ${DEST}/filter
  180. X    chmod 2755 ${DEST}/elm ${DEST}/filter
  181. X    @echo Done with installation.
  182. X
  183. Xrmt-install: remote-defined
  184. X    @echo " "
  185. X    @echo Warning: This assumes "install" has been done on the
  186. X    @echo "         remote machine.  If this is not the case you"
  187. X    @echo "         better hit BREAK quickly!"
  188. X    @echo " "
  189. X    ${CP} ${REMOTE}${DEST}/elm          ${DEST}/elm
  190. X    ${CP} ${REMOTE}${DEST}/from         ${DEST}/from
  191. X    ${CP} ${REMOTE}${DEST}/newalias     ${DEST}/newalias
  192. X    ${CP} ${REMOTE}${DEST}/printmail    ${DEST}/printmail
  193. X    ${CP} ${REMOTE}${DEST}/fastmail     ${DEST}/fastmail
  194. X    ${CP} ${REMOTE}${DEST}/readmsg      ${DEST}/readmsg
  195. X    ${CP} ${REMOTE}${DEST}/wnewmail     ${DEST}/wnewmail
  196. X    ${CP} ${REMOTE}${DEST}/newmail      ${DEST}/newmail
  197. X    ${CP} ${REMOTE}${DEST}/checkalias   ${DEST}/checkalias
  198. X    ${CP} ${REMOTE}${DEST}/messages     ${DEST}/messages
  199. X    ${CP} ${REMOTE}${DEST}/arepdaemon   ${DEST}/arepdaemon
  200. X    ${CP} ${REMOTE}${DEST}/autoreply    ${DEST}/autoreply
  201. X    ${CP} ${REMOTE}${DEST}/listalias    ${DEST}/listalias
  202. X    ${RM} ${CATMAN}/elm.1 \
  203. X          ${CATMAN}/from.1 \
  204. X              ${CATMAN}/newalias.1 \
  205. X          ${CATMAN}/printmail.1 \
  206. X          ${CATMAN}/fastmail.1 \
  207. X              ${CATMAN}/checkalias.1 \
  208. X              ${CATMAN}/autoreply.1 \
  209. X          ${CATMAN}/readmsg.1 \
  210. X          ${CATMAN}/answer.1 \
  211. X          ${CATMAN}/newmail.1 \
  212. X          ${CATMAN}/wnewmail.1 \
  213. X          ${CATMAN}/listalias.1 \
  214. X              ${CATMAN}/elm.1
  215. X    ${CP} ${REMOTE}${MAN}/elm.1        ${MAN}/elm.1
  216. X    ${CP} ${REMOTE}${MAN}/from.1       ${MAN}/from.1
  217. X    ${CP} ${REMOTE}${MAN}/newalias.1   ${MAN}/newalias.1
  218. X    ${CP} ${REMOTE}${MAN}/printmail.1  ${MAN}/printmail.1
  219. X    ${CP} ${REMOTE}${MAN}/fastmail.1   ${MAN}/fastmail.1
  220. X    ${CP} ${REMOTE}${MAN}/checkalias.1 ${MAN}/checkalias.1
  221. X    ${CP} ${REMOTE}${MAN}/autoreply.1  ${MAN}/autoreply.1
  222. X    ${CP} ${REMOTE}${MAN}/readmsg.1    ${MAN}/readmsg.1
  223. X    ${CP} ${REMOTE}${MAN}/answer.1     ${MAN}/answer.1
  224. X    ${CP} ${REMOTE}${MAN}/wnewmail.1   ${MAN}/wnewmail.1
  225. X    ${CP} ${REMOTE}${MAN}/newmail.1    ${MAN}/newmail.1
  226. X    ${CP} ${REMOTE}${MAN}/listalias.1  ${MAN}/listalias.1
  227. X    ${CP} ${REMOTE}${LIB}/elm-help.?   ${LIB}
  228. X    ${CP} ${REMOTE}${LIB}/elmrc-info   ${LIB}
  229. X    chmod a+rx ${DEST}/from ${DEST}/newalias ${DEST}/printmail \
  230. X               ${DEST}/fastmail ${DEST}/readmsg \
  231. X           ${DEST}/checkalias ${DEST}/autoreply ${DEST}/wnewmail \
  232. X           ${DEST}/newmail ${DEST}/messages ${DEST}/listalias
  233. X    chgrp mail ${DEST}/elm
  234. X    chmod 2755 ${DEST}/elm
  235. X    @echo everything is installed based on files from ${REMOTE}
  236. X
  237. Xsource: 
  238. X    tar cvf ${TAPE} bin/makelisting utils/*.c src/*.c doc/* hdrs/* \
  239. X    Instructions Makefile* utils/Makefile* src/Makefile* test/*    \
  240. X    utils/*.awk Overview filter/*.c filter/Makefile*
  241. X
  242. X# Note that the production for SHAR assumes a pretty snazzy shar program
  243. X# that can break down the output into a number of files as needed...
  244. X#   The current threshold is 60,000 bytes per file, for email/netnews
  245. X
  246. Xshar:   
  247. X    ${SHAR} *
  248. X
  249. Xlint:
  250. X    lint ${UTILSRC} > lint.out
  251. X
  252. Xlisting:
  253. X    @echo listing all source files 
  254. X    @/bin/echo \\f > LISTING
  255. X    @echo adding file 'README'...
  256. X    @cat README >> LISTING
  257. X    @/bin/echo \\f >> LISTING
  258. X    @echo adding file 'Instructions...
  259. X    @cat Instructions >> LISTING
  260. X    @/bin/echo \\f >> LISTING
  261. X    @echo adding file 'Makefile'...
  262. X    @cat Makefile >> LISTING
  263. X    @bin/makelisting Makefile ${UTILSRC} src/Makefile src/*.c hdrs/*.h \
  264. X    ${FILTSRC}
  265. X    @echo LISTING generated.
  266. X
  267. Xelm-listing: 
  268. X    @echo listing just the ELM system source files
  269. X    @echo ' ' > src/LISTING
  270. X    @cd src ; make listing ; cd ..
  271. X    @echo LISTING generated \(in directory /src\).
  272. X
  273. Xclean:
  274. X    @cd src ; make clean 
  275. X    @cd utils; make clean
  276. X    @cd filter; make clean
  277. X    @echo All spurious files removed
  278. X
  279. Xelm: bin/elm
  280. Xfilter: bin/filter
  281. Xutils: bin/utils
  282. Xutils/checkalias:
  283. Xutils/messages:
  284. Xdoc/Users.guide:
  285. Xdoc/Ref.guide:
  286. Xdoc/Alias.guide:
  287. Xdoc/Config.guide:
  288. X
  289. Xremote-defined:
  290. X    @if ( "${REMOTE}" == "" ) then; \
  291. X       echo " " ; \
  292. X       echo "You need to define 'REMOTE' as the remote file system" ; \
  293. X       echo "for this particular command.   The easiest way to do " ; \
  294. X       echo "this is to type:" ;\
  295. X       echo "    make -f <makefile> REMOTE=<remote file system> rmt-install" ; \
  296. X       echo " " ; \
  297. X     endif
  298. X    @if ( "${REMOTE}" == "" ) exit 1
  299. END_OF_Makefile
  300. if test 9596 -ne `wc -c <Makefile`; then
  301.     echo shar: \"Makefile\" unpacked with wrong size!?
  302. fi
  303. # end of overwriting check
  304. fi
  305. echo shar: Extracting \"Makefile.mstr\" \(9581 characters\)
  306. if test -f Makefile.mstr ; then 
  307.   echo shar: Will not over-write existing file \"Makefile.mstr\"
  308. else
  309. sed "s/^X//" >Makefile.mstr <<'END_OF_Makefile.mstr'
  310. X#
  311. X#  Makefile for the entire ELM mail system
  312. X#
  313. X#         (C) Copyright 1986, Dave Taylor
  314. X#
  315. X#  Last modification: October 8th, 1986
  316. X
  317. XSHELL=/bin/sh
  318. X
  319. X#########################
  320. X#
  321. X# The following entries need to be customized for the local site:  
  322. X#    The first is the address of the data-cassette drive to allow
  323. X# easy tape copies to be made, and the second is the final location 
  324. X# that all the software should be installed in when 'make install'
  325. X# is run.
  326. X#
  327. X#########################
  328. X
  329. XTAPE=   >tapeunit< 
  330. XDEST=   >dest-dir<
  331. X
  332. XLIB=    /usr/local/lib
  333. XMAN=    /usr/man/man1
  334. XCATMAN= /usr/man/cat1
  335. XSHAR=   /usr/local/bin/shar -s 60000
  336. X
  337. XDEFINE = >os-define<
  338. XLIB2   = >lib2<
  339. X
  340. X#########################
  341. X
  342. XLIBS=   >libs<
  343. XCFLAGS= -O
  344. XCC=    >cc<
  345. XRM=    >rm<
  346. XMV=     >mv<
  347. XCP=    >cp<
  348. X
  349. X# if you want to use "nroff", change this...
  350. X
  351. XFORMATTER = >troff<
  352. XTBL       = >tbl<
  353. X
  354. XDOCS=   Alias.guide Config.guide Elm.coversheet Filter.guide Ref.guide     \
  355. X    Forms.guide Users.guide answer.1 autoreply.1 checkalias.1          \
  356. X    elm.1 fastmail.1 filter.1 from.1 listalias.1 messages.1 newalias.1 \
  357. X    newmail.1 printmail.1 readmsg.1 trim-headers.1 wnewmail.1
  358. X
  359. XUTILSRC= utils/answer.c utils/arepdaemon.c utils/autoreply.c           \
  360. X    utils/fastmail.c utils/from.c utils/newalias.c \
  361. X    utils/newmail.c utils/printmail.c utils/readmsg.c utils/wnewmail.c \
  362. X    utils/trim-headers
  363. X
  364. XFILTSRC= filter/actions.c filter/filter.c filter/parse.c filter/rules.c     \
  365. X    filter/summarize.c filter/utils.c
  366. X
  367. XELMSRC=    src/addr_utils.c src/alias.c src/aliasdb.c src/aliaslib.c src/args.c  \
  368. X    src/bounceback.c src/builtin.c src/calendar.c src/connect_to.c          \
  369. X    src/curses.c src/date.c src/delete.c src/domains.c src/edit.c          \
  370. X    src/editmsg.c src/elm.c src/encode.c src/errno.c src/file.c          \
  371. X    src/file_utils.c src/fileio.c src/forms.c src/getopt.c src/hdrconfg.c \
  372. X    src/help.c src/initialize.c src/input_utils.c src/leavembox.c          \
  373. X    src/limit.c src/mailmsg1.c src/mailmsg2.c src/mailtime.c src/mkhdrs.c \
  374. X    src/newmbox.c src/opt_utils.c src/options.c src/output_utils.c        \
  375. X    src/pattern.c src/pmalloc.c src/quit.c src/read_rc.c src/remail.c     \
  376. X    src/reply.c src/return_addr.c src/save_opts.c src/savecopy.c          \
  377. X    src/screen.c src/showmsg.c src/signals.c src/softkeys.c src/sort.c    \
  378. X    src/string2.c src/strings.c src/syscall.c src/utils.c src/validname.c
  379. X
  380. XMISCHDRS  = hdrs/defs.h hdrs/sysdefs.h
  381. XELMHDRS   = hdrs/headers.h 
  382. XFILTHDRS  = hdrs/filter.h
  383. XMAINHDRS  = hdrs/elm.h
  384. X
  385. X################
  386. X
  387. Xall:    bin/elm filter utils 
  388. X    @echo Everything is up to date!
  389. X
  390. Xdocumentation:  doc/Users.fmtd doc/Ref.fmtd doc/Config.fmtd doc/Alias.fmtd \
  391. X        doc/Form.fmtd doc/Filter.fmtd
  392. X    
  393. Xdoc/Users.fmtd: doc/Users.guide
  394. X    ${TBL} doc/Users.guide | ${FORMATTER} -mm > doc/Users.fmtd
  395. X
  396. Xdoc/Form.fmtd: doc/Form.guide
  397. X    ${FORMATTER} -mm doc/Form.guide > doc/Form.fmtd
  398. X
  399. Xdoc/Filter.fmtd: doc/Filter.guide
  400. X    ${TBL} doc/Filter.guide | ${FORMATTER} -mm > doc/Filter.fmtd
  401. X
  402. Xdoc/Ref.fmtd: doc/Ref.guide
  403. X    ${FORMATTER} -mm doc/Ref.guide > doc/Ref.fmtd
  404. X
  405. Xdoc/Config.fmtd:  doc/Config.guide
  406. X    ${TBL} doc/Config.guide | ${FORMATTER} -mm > doc/Config.fmtd
  407. X
  408. Xdoc/Alias.fmtd:  doc/Alias.guide
  409. X    ${FORMATTER} -mm doc/Alias.guide > doc/Alias.fmtd
  410. X
  411. Xbin/elm: ${ELMSRC} ${MISCHDRS} ${ELMHDRS} ${MAINHDRS}
  412. X    cd src;make 'DEFINE=${DEFINE}' 'LIB2=${LIB2}' ../bin/elm
  413. X    
  414. Xbin/utils: ${UTILSRC} ${MISCHHDRS}
  415. X    cd utils; make 'DEFINE=${DEFINE}' 'LIBS=${LIB2}' all
  416. X
  417. Xbin/filter: ${FILTSRC} ${FILTHDR}
  418. X    cd filter; make 'DEFINE=${DEFINE}' 'LIBS=${LIB2}' all
  419. X
  420. Xinstall: all
  421. X    ${CP} bin/elm          ${DEST}/elm
  422. X    ${CP} bin/from         ${DEST}/from
  423. X    ${CP} bin/newalias     ${DEST}/newalias
  424. X    ${CP} bin/printmail    ${DEST}/printmail
  425. X    ${CP} bin/fastmail     ${DEST}/fastmail
  426. X    ${CP} bin/readmsg      ${DEST}/readmsg
  427. X    ${CP} bin/newmail      ${DEST}/newmail
  428. X    ${CP} bin/wnewmail     ${DEST}/wnewmail
  429. X    ${CP} bin/checkalias   ${DEST}/checkalias
  430. X    ${CP} bin/messages     ${DEST}/messages
  431. X    ${CP} bin/trim-headers ${DEST}/trim-headers
  432. X    ${CP} bin/arepdaemon   ${DEST}/arepdaemon
  433. X    ${CP} bin/autoreply    ${DEST}/autoreply
  434. X    ${CP} bin/listalias    ${DEST}/listalias
  435. X    ${CP} bin/filter       ${DEST}/filter
  436. X    ${RM} ${CATMAN}/elm.1 ${CATMAN}/from.1 \
  437. X          ${CATMAN}/newalias.1 ${CATMAN}/printmail.1 \
  438. X          ${CATMAN}/fastmail.1 ${CATMAN}/elm.1 \
  439. X          ${CATMAN}/readmsg.1 ${CATMAN}/answer.1 \
  440. X          ${CATMAN}/newmail.1 ${CATMAN}/checkalias.1 \
  441. X          ${CATMAN}/autoreply.1 ${CATMAN}/wnewmail.1 \
  442. X          ${CATMAN}/messages.1 ${CATMAN}/trim-headers.1 \
  443. X          ${CATMAN}/listalias.1 ${CATMAN}/filter.1
  444. X    ${CP} doc/elm.1        ${MAN}/elm.1
  445. X    ${CP} doc/from.1       ${MAN}/from.1
  446. X    ${CP} doc/newalias.1   ${MAN}/newalias.1
  447. X    ${CP} doc/printmail.1  ${MAN}/printmail.1
  448. X    ${CP} doc/fastmail.1   ${MAN}/fastmail.1
  449. X    ${CP} doc/checkalias.1 ${MAN}/checkalias.1
  450. X    ${CP} doc/messages.1   ${MAN}/messages.1
  451. X    ${CP} doc/trim-headers.1 ${MAN}/trim-headers.1
  452. X    ${CP} doc/autoreply.1  ${MAN}/autoreply.1
  453. X    ${CP} doc/answer.1     ${MAN}/answer.1
  454. X    ${CP} doc/readmsg.1    ${MAN}/readmsg.1
  455. X    ${CP} doc/newmail.1    ${MAN}/newmail.1
  456. X    ${CP} doc/wnewmail.1   ${MAN}/wnewmail.1
  457. X    ${CP} doc/listalias.1  ${MAN}/listalias.1
  458. X    ${CP} doc/filter.1     ${MAN}/filter.1
  459. X    ${CP} doc/elm-help.?   ${LIB}
  460. X    ${CP} doc/elmrc-info   ${LIB}
  461. X    chmod a+rx ${DEST}/from ${DEST}/newalias \
  462. X           ${DEST}/printmail ${DEST}/fastmail \
  463. X           ${DEST}/readmsg ${DEST}/trim-headers \
  464. X           ${DEST}/checkalias ${DEST}/autoreply \
  465. X           ${DEST}/newmail ${DEST}/wnewmail ${DEST}/messages \
  466. X           ${DEST}/listalias
  467. X    chgrp mail ${DEST}/elm ${DEST}/filter
  468. X    chmod 2755 ${DEST}/elm ${DEST}/filter
  469. X    @echo Done with installation.
  470. X
  471. Xrmt-install: remote-defined
  472. X    @echo " "
  473. X    @echo Warning: This assumes "install" has been done on the
  474. X    @echo "         remote machine.  If this is not the case you"
  475. X    @echo "         better hit BREAK quickly!"
  476. X    @echo " "
  477. X    ${CP} ${REMOTE}${DEST}/elm          ${DEST}/elm
  478. X    ${CP} ${REMOTE}${DEST}/from         ${DEST}/from
  479. X    ${CP} ${REMOTE}${DEST}/newalias     ${DEST}/newalias
  480. X    ${CP} ${REMOTE}${DEST}/printmail    ${DEST}/printmail
  481. X    ${CP} ${REMOTE}${DEST}/fastmail     ${DEST}/fastmail
  482. X    ${CP} ${REMOTE}${DEST}/readmsg      ${DEST}/readmsg
  483. X    ${CP} ${REMOTE}${DEST}/wnewmail     ${DEST}/wnewmail
  484. X    ${CP} ${REMOTE}${DEST}/newmail      ${DEST}/newmail
  485. X    ${CP} ${REMOTE}${DEST}/checkalias   ${DEST}/checkalias
  486. X    ${CP} ${REMOTE}${DEST}/messages     ${DEST}/messages
  487. X    ${CP} ${REMOTE}${DEST}/arepdaemon   ${DEST}/arepdaemon
  488. X    ${CP} ${REMOTE}${DEST}/autoreply    ${DEST}/autoreply
  489. X    ${CP} ${REMOTE}${DEST}/listalias    ${DEST}/listalias
  490. X    ${RM} ${CATMAN}/elm.1 \
  491. X          ${CATMAN}/from.1 \
  492. X              ${CATMAN}/newalias.1 \
  493. X          ${CATMAN}/printmail.1 \
  494. X          ${CATMAN}/fastmail.1 \
  495. X              ${CATMAN}/checkalias.1 \
  496. X              ${CATMAN}/autoreply.1 \
  497. X          ${CATMAN}/readmsg.1 \
  498. X          ${CATMAN}/answer.1 \
  499. X          ${CATMAN}/newmail.1 \
  500. X          ${CATMAN}/wnewmail.1 \
  501. X          ${CATMAN}/listalias.1 \
  502. X              ${CATMAN}/elm.1
  503. X    ${CP} ${REMOTE}${MAN}/elm.1        ${MAN}/elm.1
  504. X    ${CP} ${REMOTE}${MAN}/from.1       ${MAN}/from.1
  505. X    ${CP} ${REMOTE}${MAN}/newalias.1   ${MAN}/newalias.1
  506. X    ${CP} ${REMOTE}${MAN}/printmail.1  ${MAN}/printmail.1
  507. X    ${CP} ${REMOTE}${MAN}/fastmail.1   ${MAN}/fastmail.1
  508. X    ${CP} ${REMOTE}${MAN}/checkalias.1 ${MAN}/checkalias.1
  509. X    ${CP} ${REMOTE}${MAN}/autoreply.1  ${MAN}/autoreply.1
  510. X    ${CP} ${REMOTE}${MAN}/readmsg.1    ${MAN}/readmsg.1
  511. X    ${CP} ${REMOTE}${MAN}/answer.1     ${MAN}/answer.1
  512. X    ${CP} ${REMOTE}${MAN}/wnewmail.1   ${MAN}/wnewmail.1
  513. X    ${CP} ${REMOTE}${MAN}/newmail.1    ${MAN}/newmail.1
  514. X    ${CP} ${REMOTE}${MAN}/listalias.1  ${MAN}/listalias.1
  515. X    ${CP} ${REMOTE}${LIB}/elm-help.?   ${LIB}
  516. X    ${CP} ${REMOTE}${LIB}/elmrc-info   ${LIB}
  517. X    chmod a+rx ${DEST}/from ${DEST}/newalias ${DEST}/printmail \
  518. X               ${DEST}/fastmail ${DEST}/readmsg \
  519. X           ${DEST}/checkalias ${DEST}/autoreply ${DEST}/wnewmail \
  520. X           ${DEST}/newmail ${DEST}/messages ${DEST}/listalias
  521. X    chgrp mail ${DEST}/elm
  522. X    chmod 2755 ${DEST}/elm
  523. X    @echo everything is installed based on files from ${REMOTE}
  524. X
  525. Xsource: 
  526. X    tar cvf ${TAPE} bin/makelisting utils/*.c src/*.c doc/* hdrs/* \
  527. X    Instructions Makefile* utils/Makefile* src/Makefile* test/*    \
  528. X    utils/*.awk Overview filter/*.c filter/Makefile*
  529. X
  530. X# Note that the production for SHAR assumes a pretty snazzy shar program
  531. X# that can break down the output into a number of files as needed...
  532. X#   The current threshold is 60,000 bytes per file, for email/netnews
  533. X
  534. Xshar:   
  535. X    ${SHAR} *
  536. X
  537. Xlint:
  538. X    lint ${UTILSRC} > lint.out
  539. X
  540. Xlisting:
  541. X    @echo listing all source files 
  542. X    @/bin/echo \\f > LISTING
  543. X    @echo adding file 'README'...
  544. X    @cat README >> LISTING
  545. X    @/bin/echo \\f >> LISTING
  546. X    @echo adding file 'Instructions...
  547. X    @cat Instructions >> LISTING
  548. X    @/bin/echo \\f >> LISTING
  549. X    @echo adding file 'Makefile'...
  550. X    @cat Makefile >> LISTING
  551. X    @bin/makelisting Makefile ${UTILSRC} src/Makefile src/*.c hdrs/*.h \
  552. X    ${FILTSRC}
  553. X    @echo LISTING generated.
  554. X
  555. Xelm-listing: 
  556. X    @echo listing just the ELM system source files
  557. X    @echo ' ' > src/LISTING
  558. X    @cd src ; make listing ; cd ..
  559. X    @echo LISTING generated \(in directory /src\).
  560. X
  561. Xclean:
  562. X    @cd src ; make clean 
  563. X    @cd utils; make clean
  564. X    @cd filter; make clean
  565. X    @echo All spurious files removed
  566. X
  567. Xelm: bin/elm
  568. Xfilter: bin/filter
  569. Xutils: bin/utils
  570. Xutils/checkalias:
  571. Xutils/messages:
  572. Xdoc/Users.guide:
  573. Xdoc/Ref.guide:
  574. Xdoc/Alias.guide:
  575. Xdoc/Config.guide:
  576. X
  577. Xremote-defined:
  578. X    @if ( "${REMOTE}" == "" ) then; \
  579. X       echo " " ; \
  580. X       echo "You need to define 'REMOTE' as the remote file system" ; \
  581. X       echo "for this particular command.   The easiest way to do " ; \
  582. X       echo "this is to type:" ;\
  583. X       echo "    make -f <makefile> REMOTE=<remote file system> rmt-install" ; \
  584. X       echo " " ; \
  585. X     endif
  586. X    @if ( "${REMOTE}" == "" ) exit 1
  587. END_OF_Makefile.mstr
  588. if test 9581 -ne `wc -c <Makefile.mstr`; then
  589.     echo shar: \"Makefile.mstr\" unpacked with wrong size!?
  590. fi
  591. # end of overwriting check
  592. fi
  593. echo shar: Extracting \"src/forms.c\" \(9070 characters\)
  594. if test -f src/forms.c ; then 
  595.   echo shar: Will not over-write existing file \"src/forms.c\"
  596. else
  597. sed "s/^X//" >src/forms.c <<'END_OF_src/forms.c'
  598. X/**                forms.c                **/
  599. X
  600. X/** This set of files supports the 'forms' options (AT&T Mail Forms) to
  601. X    the mail system.  The specs are drawn from a document from AT&T entitled
  602. X    "Standard for Exchanging Forms on AT&T Mail", version 1.9.
  603. X
  604. X    (C) Copyright 1986, Dave Taylor
  605. X**/
  606. X
  607. X/** Some notes on the format of a FORM;
  608. X
  609. X    First off, in AT&T Mail parlance, this program only supports SIMPLE
  610. X    forms, currently.  This means that while each form must have three
  611. X     sections;
  612. X
  613. X        [options-section]
  614. X        ***
  615. X        [form-image]
  616. X        ***
  617. X        [rules-section]
  618. X
  619. X    this program will ignore the first and third sections completely.  The
  620. X    program will assume that the user merely enteres the form-image section,
  621. X    and will append and prepend the triple asterisk sequences that *MUST*
  622. X    be part of the message.  The messages are also expected to have a 
  623. X    specific header - "Content-Type: mailform" - which will be added on all
  624. X    outbound mail and checked on inbound...
  625. X**/
  626. X
  627. X#include "headers.h"
  628. X#include <errno.h>
  629. X
  630. Xextern int errno;
  631. X
  632. Xchar *error_name(), *strcat(), *strcpy();
  633. X
  634. Xcheck_form_file(filename)
  635. Xchar *filename;
  636. X{
  637. X    /** This routine returns the number of fields in the specified file,
  638. X        or -1 if an error is encountered. **/
  639. X
  640. X    FILE *form;
  641. X    char buffer[SLEN];
  642. X    register int field_count = 0;
  643. X
  644. X    if ((form = fopen(filename, "r")) == NULL) {
  645. X      error2("Error %s trying to open %s to check fields!",
  646. X          error_name(errno), filename);
  647. X      return(-1);
  648. X    }
  649. X    
  650. X    while (fgets(buffer, SLEN, form) != NULL) {
  651. X      field_count += occurances_of(COLON, buffer);
  652. X    }
  653. X
  654. X    fclose(form);
  655. X
  656. X    return(field_count);
  657. X}
  658. X
  659. Xformat_form(filename)
  660. Xchar *filename;
  661. X{
  662. X    /** This routine accepts a validated file that is the middle 
  663. X        section of a form message and prepends and appends the appropriate 
  664. X        instructions.  It's pretty simple. 
  665. X        This returns the number of forms in the file, or -1 on errors
  666. X    **/
  667. X    
  668. X    FILE *form, *newform;
  669. X    char  newfname[SLEN], buffer[SLEN];
  670. X    register form_count = 0;
  671. X
  672. X    dprint1(4, "Formatting form file '%s'\n", filename);
  673. X
  674. X    /** first off, let's open the files... **/
  675. X
  676. X    if ((form = fopen(filename, "r")) == NULL) {
  677. X      error("Can't read the message to validate the form!");
  678. X      dprint2(1,
  679. X              "** Error encountered opening file \"%s\" - %s (check_form) **\n",
  680. X          filename, error_name(errno));
  681. X      return(-1);
  682. X    }
  683. X
  684. X    sprintf(newfname, "%s%d", temp_form_file, getpid());
  685. X
  686. X    if ((newform = fopen(newfname, "w")) == NULL) {
  687. X      error("Couldn't open newform file for form output!");
  688. X      dprint2(1,
  689. X              "** Error encountered opening file \"%s\" - %s (check_form) **\n",
  690. X          newfname, error_name(errno));
  691. X      return(-1);
  692. X    }
  693. X
  694. X    /** the required header... **/
  695. X
  696. X    /* these are actually the defaults, but let's be sure, okay? */
  697. X
  698. X    fprintf(newform, "WIDTH=78\nTYPE=SIMPLE\nOUTPUT=TEXT\n***\n");
  699. X
  700. X    /** and let's have some fun transfering the stuff across... **/
  701. X
  702. X    while (fgets(buffer, SLEN, form) != NULL) {
  703. X      fputs(buffer, newform);
  704. X      form_count += occurances_of(COLON, buffer);
  705. X    }
  706. X
  707. X    fprintf(newform, "***\n");    /* that closing bit! */
  708. X
  709. X    fclose(form);
  710. X    fclose(newform);
  711. X
  712. X    if (form_count > 0) {
  713. X      if (unlink(filename) != 0) {
  714. X        error2("Error %s unlinking file %s", error_name(errno), filename);
  715. X        return(-1);
  716. X      }
  717. X      if (link(newfname, filename)) {
  718. X        error3("Error %s linking %s to %s", error_name(errno), 
  719. X            newfname, filename);
  720. X        return(-1);
  721. X      }
  722. X    }
  723. X
  724. X    if (unlink(newfname)) {
  725. X      error2("Error %s unlinking file %s", error_name(errno), newfname);
  726. X      return(-1);    
  727. X    }
  728. X
  729. X    return(form_count);
  730. X}
  731. X
  732. Xint
  733. Xmail_filled_in_form(address, subject)
  734. Xchar *address, *subject;
  735. X{
  736. X    /** This is the interesting routine.  This one will read the
  737. X        message and prompt the user, line by line, for each of
  738. X        the fields...returns non-zero if it succeeds
  739. X    **/
  740. X
  741. X    FILE           *fd;
  742. X    register int lines = 0, count;
  743. X    char         buffer[SLEN], *ptr;
  744. X
  745. X    dprint2(4, "replying to form with;\n\taddress=%s and\n\t subject=%s\n",
  746. X           address, subject);
  747. X
  748. X        if (fseek(mailfile, header_table[current-1].offset, 0) == -1) {
  749. X      dprint3(1,"Error: seek %ld resulted in errno %s (%s)\n", 
  750. X           header_table[current-1].offset, error_name(errno), 
  751. X           "mail_filled_in_form");
  752. X      error2("ELM [seek] couldn't read %d bytes into file (%s)",
  753. X             header_table[current-1].offset, error_name(errno));
  754. X      return(0);
  755. X        }
  756. X    /* now we can fly along and get to the message body... */
  757. X
  758. X    while ((ptr = fgets(buffer, SLEN, mailfile)) != NULL) {
  759. X      if (strlen(buffer) == 1)    /* <return> only */
  760. X        break;
  761. X      else if (strncmp(buffer,"From ", 5) == 0 && lines++ > 0) {
  762. X        error("No form in this message!?");
  763. X        return(0);
  764. X      }
  765. X    }
  766. X
  767. X    if (ptr == NULL) {
  768. X      error("No form in this message!?");
  769. X      return(0);
  770. X    }
  771. X
  772. X    dprint0(6,"- past header of form message -\n");
  773. X    
  774. X    /* at this point we're at the beginning of the body of the message */
  775. X
  776. X    /* now we can skip to the FORM-IMAGE section by reading through a 
  777. X       line with a triple asterisk... */
  778. X
  779. X    while ((ptr = fgets(buffer, SLEN, mailfile)) != NULL) {
  780. X      if (strcmp(buffer, "***\n") == 0)
  781. X        break;    /* we GOT it!  It's a miracle! */    
  782. X      else if (strncmp(buffer, "From ",5) == 0) {
  783. X        error("Badly constructed form.  Can't reply!");
  784. X        return(0);
  785. X      }
  786. X    }
  787. X
  788. X    if (ptr == NULL) {
  789. X      error("Badly constructed form.  Can't reply!");
  790. X      return(0);
  791. X    }
  792. X
  793. X    dprint0(6,"- skipped the non-forms-image stuff -\n");
  794. X    
  795. X    /* one last thing - let's open the tempfile for output... */
  796. X    
  797. X    sprintf(buffer, "%s%d", temp_form_file, getpid());
  798. X
  799. X    dprint1(2,"-- forms sending using file %s --\n", buffer);
  800. X
  801. X    if ((fd = fopen(buffer,"w")) == NULL) {
  802. X      error2("Can't open \"%s\" as output file! (%s)", buffer,
  803. X         error_name(errno));
  804. X      dprint2(1,"** Error %s encountered trying to open temp file %s;\n",
  805. X          error_name(errno), buffer);
  806. X      return(0);
  807. X    }
  808. X
  809. X    /* NOW we're ready to read the form image in and start prompting... */
  810. X
  811. X    Raw(OFF);
  812. X    ClearScreen();
  813. X
  814. X    while ((ptr = fgets(buffer, SLEN, mailfile)) != NULL) {
  815. X      dprint1(9,"- read %s", buffer);
  816. X      if (strcmp(buffer, "***\n") == 0) /* end of form! */
  817. X        break;
  818. X     
  819. X      switch ((count = occurances_of(COLON, buffer))) {
  820. X        case 0 : printf("%s", buffer);        /* output line */
  821. X             fprintf(fd, "%s", buffer);     
  822. X             break;
  823. X            case 1 : if (buffer[0] == COLON) {
  824. X                 printf(
  825. X"(Enter as many lines as needed, ending with a '.' by itself on a line)\n");
  826. X                     while (gets(buffer) != NULL)
  827. X                   if (strcmp(buffer, ".") == 0)
  828. X                     break;
  829. X                   else 
  830. X             fprintf(fd,"%s\n", buffer);
  831. X                 }
  832. X                 else 
  833. X              prompt_for_entry(buffer, fd);
  834. X                 break;
  835. X            default: prompt_for_multiple_entries(buffer, fd, count);
  836. X      }
  837. X    }
  838. X
  839. X    Raw(ON);
  840. X    fclose(fd);
  841. X
  842. X    /** let's just mail this off now... **/
  843. X
  844. X    mail_form(address, subject);
  845. X
  846. X    return(1);
  847. X}
  848. X
  849. Xprompt_for_entry(buffer, fd)
  850. Xchar *buffer;
  851. XFILE *fd;
  852. X{
  853. X    /** This is called with an entry of the form "prompt:" and will 
  854. X        display the prompt and save the prompt and the user reply
  855. X        in the file "fd"
  856. X    **/
  857. X    
  858. X    char mybuffer[SLEN];
  859. X
  860. X    no_ret(buffer);
  861. X
  862. X    dprint1(7, "prompt-for-entry \"%s\"\n", buffer);
  863. X
  864. X    printf("%s ", buffer);    fflush(stdout);
  865. X
  866. X    gets(mybuffer);
  867. X
  868. X    fprintf(fd, "%s: %s", buffer, mybuffer);
  869. X}
  870. X
  871. Xprompt_for_multiple_entries(buffer, fd, entries)
  872. Xchar *buffer;
  873. XFILE *fd;
  874. Xint  entries;
  875. X{
  876. X    /** Almost the same as the above routine, this one deals with lines
  877. X        that have multiple colons on them.  It must first figure out how
  878. X        many spaces to allocate for each field then prompts the user, 
  879. X        line by line, for the entries...
  880. X    **/
  881. X
  882. X    char mybuffer[SLEN], prompt[SLEN], spaces[SLEN];
  883. X    register int  field_size, i, j, offset = 0, extra_tabs = 0;
  884. X
  885. X    dprint2(7, "prompt-for-multiple [%d] -entries \"%s\"\n", entries,
  886. X        buffer);
  887. X
  888. X    strcpy(prompt, "No Prompt Available:");
  889. X
  890. X    while (entries--) {
  891. X      j=0; 
  892. X      i = chloc((char *) buffer + offset, COLON) + 1;
  893. X      while (j < i - 1) {
  894. X        prompt[j] = buffer[j+offset];
  895. X        j++;
  896. X      }
  897. X      prompt[j] = '\0';
  898. X
  899. X      field_size = 0;
  900. X
  901. X      while (whitespace(buffer[i+offset])) {
  902. X        if (buffer[i+offset] == TAB) {
  903. X          field_size += 8 - (i % 8);
  904. X          extra_tabs += (8 - (i % 8)) - 1;
  905. X        }
  906. X        else
  907. X          field_size += 1;
  908. X        i++;
  909. X      }
  910. X
  911. X      offset += i;
  912. X    
  913. X      if (field_size == 0)     /* probably last prompt in line... */
  914. X        field_size = 80 - (offset + extra_tabs);
  915. X
  916. X      prompt_for_sized_entry(prompt, mybuffer, field_size);
  917. X
  918. X      spaces[0] = ' ';    /* always at least ONE trailing space... */
  919. X      spaces[1] = '\0';
  920. X
  921. X      for (j = strlen(mybuffer); j < field_size; j++)
  922. X        strcat(spaces, " ");
  923. X
  924. X      fprintf(fd, "%s: %s%s", prompt, mybuffer, spaces);
  925. X      fflush(fd);
  926. X    }
  927. X
  928. X    fprintf(fd, "\n");
  929. X}
  930. X
  931. Xprompt_for_sized_entry(prompt, buffer, field_size)
  932. Xchar *prompt, *buffer;
  933. Xint   field_size;
  934. X{
  935. X    /* This routine prompts for an entry of the size specified. */
  936. X
  937. X    register int i;
  938. X
  939. X    dprint2(7, "prompt-for-sized-entry \"%s\" %d chars\n", 
  940. X        prompt, field_size);
  941. X
  942. X    printf("%s : ", prompt);
  943. X    
  944. X    for (i=0;i<field_size; i++)
  945. X      putchar('_');
  946. X    for (i=0;i<field_size; i++)
  947. X      putchar(BACKSPACE);
  948. X    fflush(stdout);
  949. X
  950. X    gets(buffer);
  951. X
  952. X    if (strlen(buffer) > field_size) buffer[field_size-1] = '\0';
  953. X}
  954. END_OF_src/forms.c
  955. if test 9070 -ne `wc -c <src/forms.c`; then
  956.     echo shar: \"src/forms.c\" unpacked with wrong size!?
  957. fi
  958. # end of overwriting check
  959. fi
  960. echo shar: Extracting \"src/return_addr.c\" \(9579 characters\)
  961. if test -f src/return_addr.c ; then 
  962.   echo shar: Will not over-write existing file \"src/return_addr.c\"
  963. else
  964. sed "s/^X//" >src/return_addr.c <<'END_OF_src/return_addr.c'
  965. X/**            return_addr.c            **/
  966. X
  967. X/** This set of routines is used to generate real return addresses
  968. X    and also return addresses suitable for inclusion in a users
  969. X    alias files (ie optimized based on the pathalias database).
  970. X
  971. X    Added: the ability to respond to messages that were originally
  972. X    sent by the user (That is, the "savemail" file format messages)
  973. X    by reading the return address, seeing the "To:" prefix and then
  974. X    calling the "get_existing_return()" routine.  Currently this does
  975. X    NOT include any "Cc" lines in the message, just the "To:" line(s).
  976. X
  977. X    Also added the PREFER_UUCP stuff for listing reasonable addresses
  978. X    and such...*sigh*
  979. X
  980. X    These routines (C) Copyright 1986 Dave Taylor
  981. X**/
  982. X
  983. X#include "headers.h"
  984. X
  985. X#include <errno.h>
  986. X
  987. X#include <sys/types.h>
  988. X#include <sys/stat.h>
  989. X
  990. Xchar *shift_lower();
  991. X
  992. Xextern int errno;
  993. X
  994. Xchar *error_name(), *strcat(), *strcpy();
  995. X
  996. X#ifndef DONT_OPTIMIZE_RETURN
  997. X
  998. Xoptimize_return(address)
  999. Xchar *address;
  1000. X{
  1001. X    /** This routine tries to create an optimized address, that is,
  1002. X        an address that has the minimal information needed to 
  1003. X        route a message to this person given the current path
  1004. X        database...
  1005. X    **/
  1006. X
  1007. X#ifdef PREFER_UUCP
  1008. X
  1009. X    /** first off, let's see if we need to strip off the localhost
  1010. X        address crap... **/
  1011. X
  1012. X    /** if we have a uucp part (e.g.a!b) AND the bogus address...**/
  1013. X
  1014. X    if (chloc(address,'!') != -1 && in_string(address, BOGUS_INTERNET))
  1015. X      address[strlen(address)-strlen(BOGUS_INTERNET)] = '\0';
  1016. X#endif
  1017. X
  1018. X    /** next step is to figure out what sort of address we have... **/
  1019. X
  1020. X    if (chloc(address, '%') != -1)
  1021. X      optimize_cmplx_arpa(address);
  1022. X    else if (chloc(address, '@') != -1)
  1023. X      optimize_arpa(address);
  1024. X    else
  1025. X      optimize_usenet(address);
  1026. X}
  1027. X
  1028. Xoptimize_cmplx_arpa(address)
  1029. Xchar *address;
  1030. X{
  1031. X    /** Try to optimize a complex ARPA address.  A Complex address is one 
  1032. X        that contains '%' (deferred '@').  For example:  
  1033. X        veeger!hpcnof!hplabs!joe%sytech@syte  
  1034. X        is a complex address (no kidding, right?).  The algorithm for 
  1035. X        trying to resolve it is to move all the way to the right, then 
  1036. X        back up left until the first '!' then from there to the SECOND 
  1037. X        metacharacter on the right is the name@host address...(in this 
  1038. X            example, it would be "joe%sytech").  Check this in the routing
  1039. X        table.  If not present, keep backing out to the right until we
  1040. X        find a host that is present, or we hit the '@' sign.  Once we
  1041. X        have a 'normal' ARPA address, hand it to optimize_arpa().
  1042. X    **/
  1043. X
  1044. X    char name[SHORT_SLEN], buffer[SLEN], junk[SLEN];
  1045. X    char host[SHORT_SLEN], old_host[SHORT_SLEN];
  1046. X    register int i, loc, nloc = 0, hloc = 0, passes = 1;
  1047. X
  1048. X    /** first off, get the name%host... **/
  1049. X
  1050. X    for (loc = strlen(address)-1; address[loc] != '!' && loc > -1; loc--)
  1051. X       ;
  1052. X
  1053. X    while (address[loc] != '\0') {
  1054. X
  1055. X      if (passes == 1) {
  1056. X        loc++;
  1057. X
  1058. X        while (address[loc] != '%' && address[loc] != '@')
  1059. X          name[nloc++] = address[loc++];
  1060. X      }
  1061. X      else {
  1062. X        for (i=0; old_host[i] != '\0'; i++)
  1063. X          name[nloc++] = old_host[i];
  1064. X      }
  1065. X
  1066. X      loc++;
  1067. X  
  1068. X      while (address[loc] != '%' && address[loc] != '@')
  1069. X        host[hloc++] = address[loc++];
  1070. X  
  1071. X      host[hloc] = name[nloc] = '\0';
  1072. X
  1073. X      strcpy(old_host, host);
  1074. X      remove_domains(host);
  1075. X
  1076. X      sprintf(buffer, "%s@%s", name, shift_lower(host));
  1077. X
  1078. X      if (expand_site(buffer, junk) == 0) {
  1079. X        strcpy(address, buffer);
  1080. X        return;
  1081. X      }
  1082. X      else if (address[loc] == '@') {
  1083. X        optimize_arpa(address);
  1084. X        return;
  1085. X      }
  1086. X      else
  1087. X        name[nloc++] = '%';    /* for next pass through */
  1088. X
  1089. X    }
  1090. X}
  1091. X
  1092. Xoptimize_arpa(address)
  1093. Xchar *address;
  1094. X{
  1095. X    /** Get an arpa address and simplify it to the minimal
  1096. X        route needed to get mail to this person... **/
  1097. X
  1098. X    char name[SHORT_SLEN], buffer[SLEN], junk[SLEN];
  1099. X    char host[SHORT_SLEN];
  1100. X    register int loc, nloc = 0, hloc = 0, at_sign = 0;
  1101. X
  1102. X    for (loc = strlen(address)-1; address[loc] != '!' && loc > -1; loc--) {
  1103. X      if (address[loc] == '@')
  1104. X         at_sign++;    /* remember this spot! */
  1105. X      else if (at_sign)
  1106. X        name[nloc++] = address[loc];
  1107. X      else
  1108. X        host[hloc++] = address[loc];
  1109. X    }
  1110. X
  1111. X    name[nloc] = host[hloc] = '\0';
  1112. X
  1113. X    reverse(name);
  1114. X    reverse(host);
  1115. X
  1116. X    remove_domains(host);
  1117. X
  1118. X    sprintf(buffer,"%s@%s", name, shift_lower(host));
  1119. X
  1120. X    if (expand_site(buffer, junk) == 0) {
  1121. X      strcpy(address, buffer);
  1122. X      return;
  1123. X    }
  1124. X
  1125. X    optimize_usenet(address);    /* that didn't work... */
  1126. X}
  1127. X    
  1128. Xoptimize_usenet(address)
  1129. Xchar *address;
  1130. X{
  1131. X    /** optimize the return address IFF it's a standard usenet
  1132. X        address...
  1133. X    **/
  1134. X
  1135. X    char name[SHORT_SLEN],  new_address[SLEN], buffer[SLEN], junk[SLEN];
  1136. X    register int loc, nloc = 0, aloc = 0, passes = 1;
  1137. X
  1138. X    for (loc = strlen(address)-1; address[loc] != '!' && loc > -1; loc--) 
  1139. X      name[nloc++] = address[loc];
  1140. X    name[nloc] = '\0';
  1141. X
  1142. X    reverse(name);
  1143. X
  1144. X    new_address[0] = '\0';    
  1145. X
  1146. X    /* got name, now get machine until we can get outta here */
  1147. X
  1148. X    while (loc > -1) {
  1149. X
  1150. X      new_address[aloc++] = address[loc--];    /* the '!' char */
  1151. X
  1152. X      while (address[loc] != '!' && loc > -1)
  1153. X        new_address[aloc++] = address[loc--];
  1154. X
  1155. X      new_address[aloc] = '\0';
  1156. X
  1157. X      strcpy(buffer, new_address);
  1158. X      reverse(buffer);
  1159. X    
  1160. X      if (expand_site(buffer, junk) == 0) {
  1161. X        if (passes == 1 && chloc(name, '@') == -1) {
  1162. X          buffer[strlen(buffer) - 1] = '\0';    /* remove '!' */
  1163. X          sprintf(address, "%s@%s", name, buffer);
  1164. X        }
  1165. X        else 
  1166. X          sprintf(address, "%s%s", buffer, name);
  1167. X        return;        /* success! */
  1168. X      }
  1169. X      passes++;
  1170. X    }
  1171. X
  1172. X    return;        /* nothing to do! */
  1173. X}
  1174. X
  1175. X#endif    not DONT_OPTIMIZE_RETURN
  1176. X
  1177. Xget_return(buffer)
  1178. Xchar *buffer;
  1179. X{
  1180. X    /** reads 'current' message again, building up the full return 
  1181. X        address including all machines that might have forwarded 
  1182. X        the message.  **/
  1183. X
  1184. X    char buf[LONG_SLEN], name1[SLEN], name2[SLEN], lastname[SLEN];
  1185. X    char hold_return[LONG_SLEN], alt_name2[SLEN];
  1186. X    int ok = 1, lines;
  1187. X
  1188. X    /* now initialize all the char buffers [thanks Keith!] */
  1189. X
  1190. X    buf[0] = name1[0] = name2[0] = lastname[0] = '\0';
  1191. X    hold_return[0] = alt_name2[0] = '\0';
  1192. X
  1193. X    /** get to the first line of the message desired **/
  1194. X
  1195. X    if (fseek(mailfile, header_table[current-1].offset, 0) == -1) {
  1196. X    dprint3(1,"Error: seek %ld bytes into file hit errno %s (%s)", 
  1197. X        header_table[current-1].offset, error_name(errno), 
  1198. X            "get_return");
  1199. X    error2("couldn't seek %d bytes into file (%s)",
  1200. X           header_table[current-1].offset, error_name(errno));
  1201. X    return;
  1202. X    }
  1203. X    /** okay!  Now we're there!  **/
  1204. X
  1205. X    lines = header_table[current-1].lines;
  1206. X    
  1207. X    buffer[0] = '\0';
  1208. X
  1209. X    while (ok && lines--) {
  1210. X      ok = (int) (fgets(buf, LONG_SLEN, mailfile) != NULL);
  1211. X      if (first_word(buf, "From ")) {
  1212. X    sscanf(buf, "%*s %s", hold_return);
  1213. X      }
  1214. X      else if (first_word(buf, ">From")) {
  1215. X    sscanf(buf,"%*s %s %*s %*s %*s %*s %*s %*s %*s %s %s", 
  1216. X           name1, name2, alt_name2);
  1217. X    if (strcmp(name2, "from") == 0)
  1218. X      strcpy(name2, alt_name2);
  1219. X    add_site(buffer, name2, lastname);
  1220. X      }
  1221. X
  1222. X#ifdef USE_EMBEDDED_ADDRESSES
  1223. X
  1224. X      else if (first_word(buf, "From:")) {
  1225. X    get_address_from("From:", buf, hold_return);
  1226. X      }
  1227. X      else if (first_word(buf, "Reply-To:")) {
  1228. X    get_address_from("Reply-To:", buf, buffer);
  1229. X    return;
  1230. X      }
  1231. X
  1232. X#endif
  1233. X
  1234. X      else if (strlen(buf) < 2)    /* done with header */
  1235. X         lines = 0; /* let's get outta here!  We're done!!! */
  1236. X     }
  1237. X
  1238. X    if (buffer[0] == '\0')
  1239. X      strcpy(buffer, hold_return); /* default address! */
  1240. X    else
  1241. X      add_site(buffer, name1, lastname);    /* get the user name too! */
  1242. X
  1243. X    if (first_word(buffer, "To:"))         /* response to savecopy!  */
  1244. X       get_existing_address(buffer);
  1245. X    else 
  1246. X       /* if we have a space character, or we DON'T have '!' or '@' chars */
  1247. X
  1248. X       if (chloc(header_table[current-1].from, ' ') >= 0 ||
  1249. X       (chloc(header_table[current-1].from, '!') < 0 &&
  1250. X        chloc(header_table[current-1].from, '@') < 0)) {
  1251. X
  1252. X     sprintf(name2, " (%s)", header_table[current-1].from);
  1253. X     strcat(buffer, name2);
  1254. X       }
  1255. X
  1256. X}
  1257. X
  1258. Xget_existing_address(buffer)
  1259. Xchar *buffer;
  1260. X{
  1261. X    /** This routine is called when the message being responded to has
  1262. X        "To:xyz" as the return address, signifying that this message is
  1263. X        an automatically saved copy of a message previously sent.  The
  1264. X        correct to address can be obtained fairly simply by reading the
  1265. X        To: header from the message itself and (blindly) copying it to
  1266. X        the given buffer.  Note that this header can be either a normal
  1267. X        "To:" line (Elm) or "Originally-To:" (previous versions e.g.Msg)
  1268. X    **/
  1269. X
  1270. X    char mybuf[LONG_STRING];
  1271. X    register char ok = 1, in_to = 0;
  1272. X
  1273. X    buffer[0] = '\0';
  1274. X
  1275. X    /** first off, let's get to the beginning of the message... **/
  1276. X
  1277. X        if (fseek(mailfile, header_table[current-1].offset, 0) == -1) {
  1278. X        dprint3(1,"Error: seek %ld bytes into file hit errno %s (%s)", 
  1279. X            header_table[current-1].offset, error_name(errno), 
  1280. X            "get_existing_address");
  1281. X        error2("couldn't seek %d bytes into the file (%s)",
  1282. X               header_table[current-1].offset, error_name(errno));
  1283. X        return;
  1284. X        }
  1285. X        /** okay!  Now we're there!  **/
  1286. X
  1287. X        while (ok) {
  1288. X          ok = (int) (fgets(mybuf, LONG_STRING, mailfile) != NULL);
  1289. X      no_ret(mybuf);    /* remove return character */
  1290. X
  1291. X          if (first_word(mybuf, "To: ")) {
  1292. X        in_to = TRUE;
  1293. X        strcpy(buffer, (char *) mybuf + strlen("To: "));
  1294. X          }
  1295. X      else if (first_word(mybuf, "Original-To:")) {
  1296. X        in_to = TRUE;
  1297. X        strcpy(buffer, (char *) mybuf + strlen("Original-To:"));
  1298. X      }
  1299. X      else if (in_to && whitespace(mybuf[0])) {
  1300. X        strcat(buffer, " ");        /* tag a space in   */
  1301. X        strcat(buffer, (char *) mybuf + 1);    /* skip 1 whitespace */
  1302. X      }
  1303. X      else if (strlen(mybuf) < 2)
  1304. X        return;                /* we're done for!  */
  1305. X      else
  1306. X        in_to = 0;
  1307. X      }
  1308. X}
  1309. END_OF_src/return_addr.c
  1310. if test 9579 -ne `wc -c <src/return_addr.c`; then
  1311.     echo shar: \"src/return_addr.c\" unpacked with wrong size!?
  1312. fi
  1313. # end of overwriting check
  1314. fi
  1315. echo shar: Extracting \"src/save_opts.c\" \(9187 characters\)
  1316. if test -f src/save_opts.c ; then 
  1317.   echo shar: Will not over-write existing file \"src/save_opts.c\"
  1318. else
  1319. sed "s/^X//" >src/save_opts.c <<'END_OF_src/save_opts.c'
  1320. X/**            save_opts.c            **/
  1321. X
  1322. X/** This file contains the routine needed to allow the users to change the
  1323. X    Elm parameters and then save the configuration in a ".elmrc" file in
  1324. X    their home directory.  With any luck this will allow them never to have
  1325. X    to actually EDIT the file!!
  1326. X
  1327. X    (C) Copyright 1986, Dave Taylor
  1328. X**/
  1329. X
  1330. X#include "headers.h"
  1331. X#include <errno.h>
  1332. X
  1333. X#undef onoff
  1334. X#define   onoff(n)    (n == 1? "ON":"OFF")
  1335. X
  1336. X#define absolute(x)        ((x) < 0? -(x) : (x))
  1337. X
  1338. Xextern  int errno;
  1339. X
  1340. Xchar *error_name(), *nameof(), *sort_name();
  1341. Xlong  ftell();
  1342. X
  1343. X#include "save_opts.h"
  1344. X
  1345. XFILE *elminfo;        /* informational file as needed... */
  1346. X
  1347. Xsave_options()
  1348. X{
  1349. X    /** Save the options currently specified to a file.  This is a
  1350. X        fairly complex routine since it tries to put in meaningful
  1351. X        comments and such as it goes along.  The comments are
  1352. X        extracted from the file ELMRC_INFO as defined in the sysdefs.h
  1353. X        file.  THAT file has the format;
  1354. X
  1355. X        varname
  1356. X          <comment>
  1357. X          <comment>
  1358. X        <blank line>
  1359. X
  1360. X        and each comment is written ABOVE the variable to be added.  This
  1361. X        program also tries to make 'pretty' stuff like the alternatives
  1362. X        and such.
  1363. X    **/
  1364. X
  1365. X    FILE *newelmrc; 
  1366. X    char  oldfname[SLEN], newfname[SLEN];
  1367. X
  1368. X    sprintf(newfname, "%s/%s", home, elmrcfile);
  1369. X    sprintf(oldfname, "%s/.old%s", home, elmrcfile);
  1370. X
  1371. X    /** first off, let's see if they already HAVE a .elmrc file **/
  1372. X
  1373. X    if (access(newfname, ACCESS_EXISTS) != -1) {
  1374. X      /** YES!  Copy it to the file ".old.elmrc".. **/
  1375. X      (void) unlink(oldfname);
  1376. X      (void) link(newfname, oldfname);
  1377. X          (void) unlink(newfname);
  1378. X      (void) chown(oldfname, userid, groupid);
  1379. X    }
  1380. X
  1381. X    /** now let's open the datafile if we can... **/
  1382. X
  1383. X    if ((elminfo = fopen(ELMRC_INFO, "r")) == NULL) 
  1384. X      error1("Warning: saving without comments - can't get to %s", 
  1385. X          ELMRC_INFO);
  1386. X
  1387. X    /** next, open the new .elmrc file... **/
  1388. X
  1389. X    if ((newelmrc = fopen(newfname, "w")) == NULL) {
  1390. X       error2("Can't save configuration: can't write to %s [%s]",
  1391. X           newfname, error_name(errno));
  1392. X       return;
  1393. X    }
  1394. X    
  1395. X    save_user_options(elminfo, newelmrc);
  1396. X
  1397. X    error1("Options saved in file %s", newfname);
  1398. X}
  1399. X
  1400. Xsave_user_options(elminfo_fd, newelmrc)
  1401. XFILE *elminfo_fd, *newelmrc;
  1402. X{
  1403. X    /** save the information in the file.  If elminfo_fd == NULL don't look
  1404. X        for comments!
  1405. X    **/
  1406. X
  1407. X    if (elminfo_fd != NULL) 
  1408. X      build_offset_table(elminfo_fd);
  1409. X
  1410. X    fprintf(newelmrc,     
  1411. X              "#\n# .elmrc - options file for the Elm mail system\n#\n");
  1412. X
  1413. X    if (strlen(full_username) > 0)
  1414. X      fprintf(newelmrc, "# Saved automatically by Elm %s for %s\n#\n\n",
  1415. X          VERSION, full_username);
  1416. X    else
  1417. X      fprintf(newelmrc, "# Saved automatically by Elm %s\n#\n\n", VERSION);
  1418. X
  1419. X    save_option_string(CALENDAR, calendar_file, newelmrc, FALSE);
  1420. X    save_option_string(EDITOR, editor, newelmrc, FALSE);
  1421. X    save_option_string(FULLNAME, full_username, newelmrc, FALSE);
  1422. X    save_option_string(MAILBOX, nameof(mailbox), newelmrc, FALSE);
  1423. X    save_option_string(MAILDIR, folders, newelmrc, FALSE);
  1424. X    save_option_string(PAGER, pager, newelmrc, FALSE);
  1425. X    save_option_string(PREFIX, prefixchars, newelmrc, TRUE);
  1426. X    save_option_string(PRINT, printout, newelmrc, FALSE);
  1427. X    save_option_string(SAVEMAIL, savefile, newelmrc, FALSE);
  1428. X    save_option_string(SHELL, shell, newelmrc, FALSE);
  1429. X
  1430. X    save_option_string(LOCALSIGNATURE, local_signature, newelmrc, FALSE);
  1431. X    save_option_string(REMOTESIGNATURE, remote_signature, newelmrc, FALSE);
  1432. X
  1433. X    save_option_sort(SORTBY, sortby, newelmrc);
  1434. X
  1435. X    save_option_on_off(ALWAYSDELETE, always_del, newelmrc);
  1436. X    save_option_on_off(ALWAYSLEAVE, always_leave, newelmrc);
  1437. X    save_option_on_off(ARROW, arrow_cursor, newelmrc);
  1438. X    save_option_on_off(AUTOCOPY, auto_copy, newelmrc);
  1439. X
  1440. X    save_option_number(BOUNCEBACK, bounceback, newelmrc);
  1441. X
  1442. X    save_option_on_off(COPY, auto_cc, newelmrc);
  1443. X/**    save_option_on_off(EDITOUT, edit_outbound, newelmrc);             **/
  1444. X    save_option_on_off(FORMS, allow_forms, newelmrc);
  1445. X    save_option_on_off(KEYPAD, hp_terminal, newelmrc);
  1446. X    save_option_on_off(MENU, mini_menu, newelmrc);
  1447. X    save_option_on_off(MOVEPAGE, move_when_paged, newelmrc);
  1448. X    save_option_on_off(NAMES, names_only, newelmrc);
  1449. X    save_option_on_off(NOHEADER, noheader, newelmrc);
  1450. X    save_option_on_off(POINTNEW, point_to_new, newelmrc);
  1451. X    save_option_on_off(RESOLVE, resolve_mode, newelmrc);
  1452. X    save_option_on_off(SAVENAME, save_by_name, newelmrc);
  1453. X    save_option_on_off(SOFTKEYS, hp_softkeys, newelmrc);
  1454. X
  1455. X    save_option_number(TIMEOUT, timeout, newelmrc);
  1456. X
  1457. X    save_option_on_off(TITLES, title_messages, newelmrc);
  1458. X
  1459. X    save_option_number(USERLEVEL, user_level, newelmrc);
  1460. X
  1461. X    save_option_on_off(WARNINGS, warnings, newelmrc);
  1462. X    save_option_on_off(WEED, filter, newelmrc);
  1463. X
  1464. X    save_option_weedlist(WEEDOUT, weedlist, newelmrc);
  1465. X    save_option_alternatives(ALTERNATIVES, alternative_addresses, newelmrc);
  1466. X
  1467. X    fflush(elminfo_fd);    /* make sure we're clear... */
  1468. X    fclose(elminfo_fd);
  1469. X}
  1470. X
  1471. Xsave_option_string(index, value, fd, underscores)
  1472. Xint index, underscores;
  1473. Xchar *value;
  1474. XFILE *fd;
  1475. X{
  1476. X    /** Save a string option to the file... only subtlety is when we
  1477. X        save strings with spaces in 'em - translate to underscores!
  1478. X    **/
  1479. X
  1480. X    register int i;
  1481. X    char     buffer[SLEN];
  1482. X    
  1483. X    if (strlen(value) == 0) return;        /* why bother? */
  1484. X
  1485. X    add_comment(index, fd);
  1486. X    
  1487. X    strcpy(buffer, value);
  1488. X
  1489. X    if (underscores)
  1490. X      for (i=0; i < strlen(buffer); i++)
  1491. X        if (buffer[i] == SPACE) buffer[i] = '_';
  1492. X
  1493. X    fprintf(fd, "%s = %s\n\n", save_info[index].name, buffer);
  1494. X}
  1495. X       
  1496. Xsave_option_sort(index, value, fd)
  1497. Xint index;
  1498. Xchar *value;
  1499. XFILE *fd;
  1500. X{
  1501. X    /** save the current sorting option to a file **/
  1502. X
  1503. X    add_comment(index, fd);
  1504. X
  1505. X    fprintf(fd, "%s = %s\n\n", save_info[index].name,
  1506. X        sort_name(SHORT));
  1507. X}
  1508. X
  1509. Xsave_option_number(index, value, fd)
  1510. Xint index, value;
  1511. XFILE *fd;
  1512. X{
  1513. X    /** Save a binary option to the file - boy is THIS easy!! **/
  1514. X
  1515. X    add_comment(index, fd);
  1516. X    
  1517. X    fprintf(fd, "%s = %d\n\n", save_info[index].name, value);
  1518. X}
  1519. X
  1520. Xsave_option_on_off(index, value, fd)
  1521. Xint index, value;
  1522. XFILE *fd;
  1523. X{
  1524. X    /** Save a binary option to the file - boy is THIS easy!! **/
  1525. X
  1526. X    add_comment(index, fd);
  1527. X    
  1528. X    fprintf(fd, "%s = %s\n\n", save_info[index].name, onoff(value));
  1529. X}
  1530. X
  1531. Xsave_option_weedlist(index, list, fd)
  1532. Xint index;
  1533. Xchar *list[];
  1534. XFILE *fd;
  1535. X{
  1536. X    /** save a list of weedout headers to the file **/
  1537. X
  1538. X    int length_so_far = 0, i;
  1539. X
  1540. X    add_comment(index, fd);
  1541. X
  1542. X    length_so_far = strlen(save_info[index].name) + 4;
  1543. X
  1544. X    fprintf(fd, "%s = ", save_info[index].name);
  1545. X
  1546. X    /** first off, skip till we get past the default list **/
  1547. X
  1548. X    for (i = 0; i < weedcount; i++) 
  1549. X      if (strcmp(weedlist[i],"*end-of-defaults*") == 0)
  1550. X        break;
  1551. X
  1552. X    while (i < weedcount) {
  1553. X      if (strlen(weedlist[i]) + length_so_far > 78) {
  1554. X        fprintf(fd, "\n\t");
  1555. X        length_so_far = 8;
  1556. X      }
  1557. X      fprintf(fd, "\"%s\" ", weedlist[i]);
  1558. X      length_so_far += (strlen(weedlist[i]) + 4);
  1559. X      i++;
  1560. X    }
  1561. X    fprintf(fd, "\n\n");
  1562. X}
  1563. X
  1564. Xsave_option_alternatives(index, list, fd)
  1565. Xint index;
  1566. Xstruct addr_rec *list;
  1567. XFILE *fd;
  1568. X{
  1569. X    /** save a list of options to the file **/
  1570. X    int length_so_far = 0;
  1571. X    struct addr_rec     *alternate;
  1572. X
  1573. X    if (list == NULL) return;    /* nothing to do! */
  1574. X
  1575. X    add_comment(index, fd);
  1576. X
  1577. X    alternate = list;    /* don't LOSE the top!! */
  1578. X
  1579. X    length_so_far = strlen(save_info[index].name) + 4;
  1580. X
  1581. X    fprintf(fd, "%s = ", save_info[index].name);
  1582. X
  1583. X    while (alternate != NULL) {
  1584. X      if (strlen(alternate->address) + length_so_far > 78) {
  1585. X        fprintf(fd, "\n\t");
  1586. X        length_so_far = 8;
  1587. X      }
  1588. X      fprintf(fd, "%s  ", alternate->address);
  1589. X      length_so_far += (strlen(alternate->address) + 3);
  1590. X      alternate = alternate->next;
  1591. X    }
  1592. X    fprintf(fd, "\n\n");
  1593. X}
  1594. X
  1595. Xadd_comment(index, fd)
  1596. Xint index;
  1597. XFILE *fd;
  1598. X{    
  1599. X    /** get to and add the comment to the file **/
  1600. X    char buffer[SLEN];
  1601. X
  1602. X    /** first off, add the comment from the comment file, if available **/
  1603. X
  1604. X    if (save_info[index].offset > 0L) {
  1605. X      if (fseek(elminfo, save_info[index].offset, 0)) {
  1606. X        dprint2(1,"** error %s seeking to %ld in elm-info file!\n",
  1607. X             error_name(errno), save_info[index].offset);
  1608. X      }
  1609. X      else while (fgets(buffer, SLEN, elminfo) != NULL) {
  1610. X        if (buffer[0] != '#') 
  1611. X           break;
  1612. X        else
  1613. X           fprintf(fd, "%s", buffer);
  1614. X      }
  1615. X    }
  1616. X}
  1617. X
  1618. Xbuild_offset_table(elminfo_fd)
  1619. XFILE *elminfo_fd;
  1620. X{
  1621. X    /** read in the info file and build the table of offsets.
  1622. X        This is a rather laborious puppy, but at least we can
  1623. X        do a binary search through the array for each element and
  1624. X        then we have it all at once!
  1625. X    **/
  1626. X
  1627. X    char line_buffer[SLEN];
  1628. X    
  1629. X    while (fgets(line_buffer, SLEN, elminfo_fd) != NULL) {
  1630. X      if (strlen(line_buffer) > 1)
  1631. X        if (line_buffer[0] != '#' && !whitespace(line_buffer[0])) {
  1632. X           no_ret(line_buffer);
  1633. X           if (find_and_store_loc(line_buffer, ftell(elminfo_fd))) {
  1634. X             dprint1(1, "** Couldn't find and store \"%s\" **\n", 
  1635. X             line_buffer);
  1636. X           }
  1637. X        }
  1638. X    }
  1639. X}
  1640. X
  1641. Xfind_and_store_loc(name, offset)
  1642. Xchar *name;
  1643. Xlong  offset;
  1644. X{
  1645. X    /** given the name and offset, find it in the table and store it **/
  1646. X
  1647. X    register int first = 0, last, middle, compare;
  1648. X
  1649. X    last = NUMBER_OF_SAVEABLE_OPTIONS;
  1650. X
  1651. X    while (first <= last) {
  1652. X
  1653. X      middle = (first+last) / 2;
  1654. X
  1655. X      if ((compare = strcmp(name, save_info[middle].name)) < 0) /* a < b */
  1656. X        last = middle - 1;
  1657. X      else if (compare == 0) {                    /* a = b */
  1658. X        save_info[middle].offset = offset;
  1659. X        return(0);
  1660. X      }
  1661. X      else  /* greater */                        /* a > b */
  1662. X        first = middle + 1; 
  1663. X    }
  1664. X
  1665. X    return(-1);
  1666. X}
  1667. END_OF_src/save_opts.c
  1668. if test 9187 -ne `wc -c <src/save_opts.c`; then
  1669.     echo shar: \"src/save_opts.c\" unpacked with wrong size!?
  1670. fi
  1671. # end of overwriting check
  1672. fi
  1673. echo shar: End of archive 9 \(of 19\).
  1674. cp /dev/null ark9isdone
  1675. DONE=true
  1676. for I in 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 ; do
  1677.     if test ! -f ark${I}isdone ; then
  1678.     echo shar: You still need to run archive ${I}.
  1679.     DONE=false
  1680.     fi
  1681. done
  1682. if test "$DONE" = "true" ; then
  1683.     echo You have unpacked all 19 archives.
  1684.     echo "See the Instructions file"
  1685.     rm -f ark[1-9]isdone ark[1-9][0-9]isdone
  1686. fi
  1687. ##  End of shell archive.
  1688. exit 0
  1689.